﻿using Bnbjoy.Business.Abstract;
using Bnbjoy.Business.Model.Account;
using Bnbjoy.Domain.Abstract;
using Bnbjoy.Domain.Concrete;
using Bnbjoy.Domain.Entities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bnbjoy.Business.Concrete
{
    public class AccountService<T> : IAccountService where T : class
    {
        IRoleRepository _roleRepository;
        IPermissionRepository _permissionRepository;
        IUserRepository _userRepository;
        IProfileRepository _profileRepository;

        public AccountService(T t) 
        {
            if (typeof(T) == typeof(IRoleRepository)) 
            {
                _roleRepository = new RoleRepository();
            }

            if (typeof(T) == typeof(IPermissionRepository)) 
            {
                _permissionRepository = new PermissionRepository();
            }

            if (typeof(T) == typeof(IUserRepository)) 
            {
                _userRepository = new UserRepository();
            }

            if (typeof(T) == typeof(IProfileRepository)) 
            {
                _profileRepository = new ProfileRepository();
            }
        }

        public async Task<bool> AddRole(Role role) 
        {
            return await _roleRepository.Insert(role);
        }

        public async Task<bool> AddPermission(Permission permission) 
        {
            return await _permissionRepository.Insert(permission);
        }

        public async Task<bool> AddUser(User user, Profile profile) 
        {
            return await _userRepository.Insert(user, profile);
        }

        public async Task<bool> AddProfile(Profile profile) 
        {
            return await _profileRepository.Insert(profile);
        }

        public async Task<User> FindUser(string mobileNumber) 
        {
            var user = await _userRepository.FindByMobileNumber(mobileNumber);
            return user;
        }

        public async Task<User> FindUser(string userName, string password)
        {
            return await _userRepository.Find(userName, password);
        }

        public async Task<User> ReadUserInfo(string userName) 
        {
            return await _userRepository.Retreive(userName);
        }

        public async Task<IEnumerable<dynamic>> FetchBA_Bnbs(string userName) 
        {
            return await _userRepository.RetreiveBA_Bnbs(userName);
        }

        public async Task<IEnumerable<dynamic>> FetchBE_Bnbs(string userName) 
        {
            return await _userRepository.RetreiveBE_Bnbs(userName);
        }

        public async Task<dynamic> ReadUserAndPermission(string userId, string role, string bnbId) 
        {
            dynamic result = await _userRepository.RetreiveUserAndPermission(userId, role, bnbId);
            return result;
        }

        public async Task<OwnerAndEmployeeModel> ReadUserDetailInfo(string userName)
        {
            dynamic result = await _userRepository.UserAndProfileInfo(userName);
            string userDetailInfoJson = JsonConvert.SerializeObject(result);
            OwnerAndEmployeeModel ownerDetailInfo = JsonConvert.DeserializeObject<OwnerAndEmployeeModel>(userDetailInfoJson);
            return ownerDetailInfo;
        }

        public async Task<IEnumerable<EmployeeModel>> ReadRelatedEmployeesInfo(string ownerId) 
        {
            IEnumerable<dynamic> result = await _userRepository.RetreiveEmployeesInfo(ownerId);
            IEnumerable<EmployeeModel> list = new List<EmployeeModel>();
            string employeesInfoJson = JsonConvert.SerializeObject(result);
            list = JsonConvert.DeserializeObject<IEnumerable<EmployeeModel>>(employeesInfoJson);

            return list;
        }

        public async Task<User> FindUserByEmail(string email) 
        {
            var user = await _userRepository.FindByMobileNumber(email);
            return user;
        }

        public async Task<bool> ChangePermission(string userId, string bnbId, string rightsStr) 
        {
            dynamic rightsObj = JsonConvert.DeserializeObject<dynamic>(rightsStr);
            if (rightsObj == null)
                return false;
            
            List<int> list = new List<int>();
            foreach (var item in rightsObj) 
            {
                if (item.key == Constants.Constants.DashboardManagement && item.value == true)
                    list.Add(1);

                if (item.key == Constants.Constants.OrdersInfoManagement && item.value == true)
                    list.Add(2);

                if (item.key == Constants.Constants.BnbInfoManagement && item.value == true)
                    list.Add(3);

                if (item.key == Constants.Constants.RoomInfoManagement && item.value == true)
                    list.Add(4);

                if (item.key == Constants.Constants.SocialManagement && item.value == true)
                    list.Add(5);

                if (item.key == Constants.Constants.CustomerInfoManagement && item.value == true)
                    list.Add(6);

                if (item.key == Constants.Constants.StatisticsInfoManagement && item.value == true)
                    list.Add(7);

                if (item.key == Constants.Constants.SettingsManagement && item.value == true)
                    list.Add(8);
            }

            string rightsResult = string.Join(",", list.ToArray());
            return await _userRepository.UpdatePermission(userId, bnbId, rightsResult);
        }

        public async Task<IEnumerable<EmployeeBnbPermissionModel>> ReadEmployeeBnbPermissionList(string userId) 
        {
            IEnumerable<dynamic> list = await _userRepository.BnbPermissionList(userId);
            string listJson = JsonConvert.SerializeObject(list);
            IEnumerable<EmployeeBnbPermissionModel> resultList = new List<EmployeeBnbPermissionModel>();
            resultList = JsonConvert.DeserializeObject<List<EmployeeBnbPermissionModel>>(listJson);
            return resultList;
        }

        public async Task<IEnumerable<dynamic>> AddRemoveBnbPermission(AddRemoveBnbPermissionParam param) 
        {
            List<Tuple<string, bool>> list = new List<Tuple<string, bool>>();
            foreach (var item in param.Items) 
            {
                list.Add(new Tuple<string, bool>(item.BnbId, item.Value));
            }

            IEnumerable<dynamic> result = await _userRepository.InsertDeleteBnbPermission(param.UserId, list);
            return result;
        }

        public void Dispose() 
        {
           
        }
    }
}
